/**
 * @author balancejia
 * @date 2016-11-22
 *       对adminlte-ui的标签页打开方式的支持，提供三种打开方式，简洁方式：openUrl、openHtml，功能齐全方式：open
 */
if (typeof (thx) == "undefined") {
	var thx = {};
}

thx.Tab = function(tabUI, contentUI, prevUI, nextUI, maxSize) {
	this.tabItems = new Array();
	this.tabUI = $(tabUI);
	this.contentUI = $(contentUI);
	this.maxSize = maxSize;// 打开的最多标签个数

	$(document).click(function() {
		$(tabUI+" ul.dropdown-menu").hide();
	});
	
	this.prevNav = new thx.navigation(this, prevUI, "P");
	this.nextNav = new thx.navigation(this, nextUI, "N");
};

/**
 * 打开远程内容
 *
 * @param title
 *            标签主键，不能重复
 * @param url
 * @param params
 * @param closeable
 * @param refreshable
 */
thx.Tab.prototype.openUrl = function(title, url, params, closeable, refreshable) {
	var closeable_ = typeof (closeable) == 'undefined' ? true : closeable;
	var refreshable_ = typeof (refreshable) == 'undefined' ? false : refreshable;
	this.open({
		title : title,
		contentSourceType : "remote",// remote|local
		url : url,
		closeable : closeable_,
		refreshable : refreshable_,
		activeFun : null,// 激活时调用函数
		closeFun : null,// 关闭时调用函数
		refreshFun : null
	});
};

/**
 * 打开客户端本地内容
 *
 * @param title
 *            标签主键，不能重复
 * @param html
 * @param closeable
 * @param refreshable
 */
thx.Tab.prototype.openHtml = function(title, html, closeable, refreshable) {
	var closeable_ = typeof (closeable) == 'undefined' ? true : closeable;
	var refreshable_ = typeof (refreshable) == 'undefined' ? false : refreshable;
	this.open({
		title : title,
		contentSourceType : "local",// remote|local
		htmlContent : html,
		closeable : closeable_,
		refreshable : refreshable_,
		activeFun : null,// 激活时调用函数
		closeFun : null,// 关闭时调用函数
		refreshFun : null
	});
};

/**
 *
 * @param params格式 {
 *            title:"", contentSourceType:remote,//remote|local url:"",
 *            htmlContent:"", closeable:true, refreshable:true,
 *            activeFun:function(){},//激活时调用函数 closeFun:function(){},//关闭时调用函数
 *            refreshFun:function(){}//刷新时调用函数 }
 */
thx.Tab.prototype.open = function(params) {
	var title = params.title;
	for (var i = 0; i < this.tabItems.length; i++) {
		var tl = this.tabItems[i].title;
		if (tl == title) {// 已经打开了
			this.tabItems[i].click();
			if(!this.tabItems[i].visible){//如果当前标签不可见
				var firstVisibleIndex = 0; //第一个可见的tab索引
				for(var j = 0; j < this.tabItems.length; j++){
					if(this.tabItems[j].visible){//第一个可见的tab
						firstVisibleIndex = j;
						break;
					}
				}
				var lastVisibleIndex = firstVisibleIndex + this.maxSize - 1;
				for(var j = 0; j < this.tabItems.length; j++){
					if(this.tabItems[j].visible){//j可见 ,i不可见    i != j
						//i < j  i < firstVisibleIndex <= j <= lastVisibleIndex;
						//i > j  firstVisibleIndex <= j <= lastVisibleIndex < i;
						if((i < firstVisibleIndex && firstVisibleIndex <= j && j <= lastVisibleIndex && (j - i) >= this.maxSize) || (firstVisibleIndex <= j && j <= lastVisibleIndex && lastVisibleIndex < i && (i - j) >= this.maxSize)){
							this.tabItems[j].hide();
						}
					}else{//j不可见,i不可见
						//i = j  j = i < firstVisibleIndex ; lastVisibleIndex < j = i
						//i < j  i < j < firstVisibleIndex ; i < firstVisibleIndex < lastVisibleIndex < j ; lastVisibleIndex < i < j
						//i > j  j < i < firstVisibleIndex ; j < firstVisibleIndex < lastVisibleIndex < i ; lastVisibleIndex < j < i   
						if((i == j) || (i < j && j < firstVisibleIndex && (j - i) < this.maxSize) || (i > j && j > lastVisibleIndex && (i - j) < this.maxSize)){
							this.tabItems[j].show();
						}
					}
				}
				if(this.tabItems[0].visible){
					this.prevNav.hide();
				}else{
					this.prevNav.show();
				}
				if(this.tabItems[this.tabItems.length - 1].visible){
					this.nextNav.hide();
				}else{
					this.nextNav.show();
				}
			}
			return;
		}
	}
	
	if(this.tabItems.length >= this.maxSize){
		var n = this.tabItems.length - this.maxSize;
		for(var i = 0; i < this.tabItems.length; i++){
			if(i <= n){
				this.tabItems[i].hide();
			}else{
				this.tabItems[i].show();
			}
		}
		this.prevNav.show();
		this.nextNav.hide();
	}

	params.index = this.tabItems.length;
	var tabItem = new thx.TabItem(params, this);

	tabItem.visible = true;
	
	if (this.tabItems.length == 0)
		this.firstItem = tabItem;
	
	this.tabItems.push(tabItem);

	if (this.activeItem)
		this.prevItem = this.activeItem;

	this.activeItem = tabItem;

	this.tabUI.append(tabItem.ui);

	var tab = this;
	if (params.contentSourceType == "remote") {
		$.ajax({
			url : ctxPath + "/" + params.url,
			type : "POST",
			async : false,
			success : function(html) {
				var content = $(html);
				tab.contentUI.append(content);
				tab.activeItem.contentUI = content;
				if (tab.prevItem)
					tab.prevItem.quiet();
				tab.activeItem.activate();
			}
		});
	} else if (params.contentSourceType == "local") {
		var content = $(params.htmlContent);
		this.contentUI.append(content);
		tabItem.contentUI = content;
		if (this.prevItem)
			tab.prevItem.quiet();
		tabItem.activate();
	}
};

thx.Tab.prototype.prev = function() {
	for(var i = 0; i < this.tabItems.length; i++){
		if(this.tabItems[i].visible){
			this.tabItems[i - 1].show();
			this.tabItems[i + this.maxSize - 1].hide();
			break;
		}
	}
	if(this.tabItems[0].visible){
		this.prevNav.hide();
	}
	if(!this.tabItems[this.tabItems.length - 1].visible){
		this.nextNav.show();
	}
};

thx.Tab.prototype.next = function() {
	for(var i = 0; i < this.tabItems.length; i++){
		if(this.tabItems[i].visible){
			this.tabItems[i].hide();
			this.tabItems[i + this.maxSize].show();
			break;
		}
	}
	if(this.tabItems[this.tabItems.length - 1].visible){
		this.nextNav.hide();
	}
	if(!this.tabItems[0].visible){
		this.prevNav.show();
	}
};

thx.TabItem = function(params, tab) {
	this.tab = tab;
	var title = params.title;
	var closeable = params.closeable;
	var refreshable = params.refreshable;
	var shortTitle = title.length > 5 ? (title.substr(0, 5) + "...") : title;

	var closeIon = closeable ? '<span class="tab-close-btn ion-close-circled" title="关闭"></span>' : '';
	var refreshIon = refreshable ? '<span class="tab-refresh-btn ion-refresh" title="刷新"></span>' : '';
	var ion = closeable ? closeIon : refreshIon;
	
	var refreshLi = '<li class="tab-refresh-btn"><a href="javascript:void(0);">刷新</a></li>';
	var closeThisLi = '<li class="tab-close-btn"><a href="javascript:void(0);">关闭当前</a></li>';
	var closeOtherLi = '<li class="tab-close-other-btn"><a href="javascript:void(0);">关闭其它</a></li>';
	var closeAllLi = '<li class="tab-close-all-btn"><a href="javascript:void(0);">关闭全部</a></li>';
	var subUl = '<ul class="dropdown-menu" role="menu" style="min-width:100px">' + refreshLi + closeThisLi + closeOtherLi + closeAllLi + '</ul>';
	var html = '<li class="active" title="' + title + '" style="max-width:105px"><a href="javascript:void(0);">' + shortTitle + ion + '</a>' + subUl + '</li>';
	
	this.ui = $(html);
	var tabItem = this;
	this.ui.click(function() {
		tabItem.ui.find("ul.dropdown-menu").hide();
		tabItem.click();
	});
	
	this.ui.mousedown(function(event){
		var e = event || window.event;
		if(e.button == 2){//右击事件
			var closeOther = false;
			for(var i = 0; i < tabItem.tab.tabItems.length; i++){
				if(tabItem.tab.tabItems[i].closeable && tabItem.tab.tabItems[i].title != tabItem.title){//存在可关闭的非当前标签
					tabItem.ui.find("li.tab-close-other-btn").show();
					tabItem.ui.find("li.tab-close-other-btn").unbind("click").bind("click", function(){
						tabItem.closeOthers();
					});
					tabItem.ui.find("li.tab-close-all-btn").show();
					tabItem.ui.find("li.tab-close-all-btn").unbind("click").bind("click", function(){
						tabItem.closeAll();
					}); 
					closeOther = true;
					break;
				}
			}
			if(!closeOther){
				tabItem.ui.find("li.tab-close-other-btn").hide();
				tabItem.ui.find("li.tab-close-other-btn").unbind("click"); 
				tabItem.ui.find("li.tab-close-all-btn").hide();
				tabItem.ui.find("li.tab-close-all-btn").unbind("click"); 
			}
			this.oncontextmenu = function(){
				tabItem.ui.find("ul.dropdown-menu").show();
				return false;//禁用默认的鼠标右键
			}
		}
	});

	if(closeable){
		this.ui.find(".tab-close-btn").click(function(event) {
			tabItem.close();
			event.stopPropagation();
		});
	}else{
		this.ui.find("li.tab-close-btn").hide();
	}

	if(refreshable){
		this.ui.find(".tab-refresh-btn").click(function(event) {
			tabItem.ui.find("ul.dropdown-menu").hide();
			tabItem.refresh();
			event.stopPropagation();
		});
	}else{
		this.ui.find("li.tab-refresh-btn").hide();
	}
	
	this.title = title;
	this.closeable = closeable;
	this.refreshable = refreshable;
	this.index = params.index;
	this.activeFun = params.activeFun;
	this.closeFun = params.closeFun;
	this.refreshFun = params.refreshFun;
	this.contentSourceType = params.contentSourceType;
	this.url = params.url;
};

thx.TabItem.prototype.click = function() {
	if (this.tab.activeItem && this.tab.activeItem.index != this.index) {
		this.tab.activeItem.quiet();
		this.tab.prevItem = this.tab.activeItem;
		this.tab.activeItem = this;
		this.activate();
	}
};

thx.TabItem.prototype.activate = function() {
	this.active = true;
	this.ui.addClass("active");
	this.contentUI.show();
	if (this.activeFun)
		this.activeFun();
};

thx.TabItem.prototype.close = function() {
	if (this.active) {
		if (this.tab.prevItem) {
			this.tab.prevItem.click();
		} else if (this.tab.firstItem) {
			this.tab.firstItem.click();
		}
	}

	if (this.closeFun)
		this.closeFun();
	
	var index = this.index;

	if (this.tab.prevItem && this.tab.prevItem.index ==index ) {
		this.tab.prevItem = null;
	}
	
	this.tab.tabItems.splice(this.index, 1);//
	for (var i = this.index; i < this.tab.tabItems.length; i++) {
		this.tab.tabItems[i].index = i;
	}
	
	if(this.tab.firstItem && this.tab.firstItem.index == index){
		this.tab.firstItem = this.tab.tabItems[0];
	}
	
	this.ui.remove();
	this.contentUI.remove();//
	
	if(this.tab.tabItems.length >= this.tab.maxSize){
		if(this.tab.tabItems[0].visible){
			this.tab.tabItems[this.tab.maxSize - 1].show();
			this.tab.prevNav.hide();
			if(!this.tab.tabItems[this.tab.tabItems.length - 1].visible){
				this.tab.nextNav.show();
			}else{
				this.tab.nextNav.hide();
			}
		}else if(this.tab.tabItems[this.tab.tabItems.length - 1].visible){
			this.tab.tabItems[this.tab.tabItems.length - this.tab.maxSize].show();
			this.tab.nextNav.hide();
			if(!this.tab.tabItems[0].visible){
				this.tab.prevNav.show();
			}else{
				this.tab.prevNav.hide();
			}
		}else{
			for(var i = 0; i < this.tab.tabItems.length; i++){
				if(this.tab.tabItems[i].visible){
					this.tab.tabItems[i - 1].show();
					break;
				}
			}
			if(!this.tab.tabItems[0].visible){
				this.tab.prevNav.show();
			}else{
				this.tab.prevNav.hide();
			}
			if(!this.tab.tabItems[this.tab.tabItems.length - 1].visible){
				this.tab.nextNav.show();
			}else{
				this.tab.nextNav.hide();
			}
		}
	}
};

thx.TabItem.prototype.closeOthers = function() {
	for(var i = 0; i < this.tab.tabItems.length; i++){
		if(this.tab.tabItems[i].closeable && this.tab.tabItems[i].title != this.title){//可关闭的非当前标签
			this.tab.tabItems[i].close();
			i = i - 1;
		}
	}
};

thx.TabItem.prototype.closeAll = function() {
	this.closeOthers();
	if(this.closeable){
		this.close();
	}
};

thx.TabItem.prototype.refresh = function() {
	if (this.contentSourceType == "local")
		return;
	var tabItem = this;
	$.ajax({
		url : ctxPath + "/" + tabItem.url,
		type : "POST",
		success : function(html) {
			tabItem.contentUI.remove();
			var content = $(html);
			tabItem.tab.contentUI.append(content);
			tabItem.contentUI = content;
			tabItem.click();
		}
	});
};

thx.TabItem.prototype.quiet = function() {//
	this.active = false;
	this.ui.removeClass("active");
	if (this.contentUI)
		this.contentUI.hide();//
};

thx.TabItem.prototype.hide = function() {//
	this.visible = false;
	this.ui.hide();
};

thx.TabItem.prototype.show = function() {//
	this.visible = true;
	this.ui.show();
};

thx.navigation = function(tab, navUI, sign){
	this.navUI = $(navUI);
	var nav = this;
	this.navUI.click(function(){
		nav.click(tab, sign);
	});
};

thx.navigation.prototype.click = function(tab, sign){
	if(sign == 'P'){
		tab.prev();
	}else{
		tab.next();
	}
};

thx.navigation.prototype.hide = function() {
	this.navUI.hide();
};

thx.navigation.prototype.show = function() {
	this.navUI[0].style.display = 'inline-block';
};
